Wayland

Wayland is a display server protocol for UNIX-ish operating systems, replacing the X11 protocol. I use it every day via river and tarazed.

Many people seem to strongly dislike it, but I don't find their arguments very compelling. There are things I myself do not like about wayland, more on that below, but they are curiously never mentioned by those people.

I have written a few utility programs for wayland. As with all my projects, no generative AI was used in their creation, at all. Note that my river related wayland projects are not listed here.

Critique

The Wayland protocol is no doubt an improvement over X11 in almost all areas. Some people may disagree, but they are wrong. However there are still issues with it that I have encountered while writing Wayland software.

The protocol was stabilized way too early. One of the biggest issue that the core protocol has is the ambiguous lifetime of global interfaces; the registry can not be freed without using the new wl_fixes interface. Also adding destructor requests for some early interfaces was forgotten. They were added in later, but because libwayland always adds a destroy function, even if no corresponding request exists, they were not called "destroy" as that would break bug-compatibility for libwayland. Instead these interfaces now have "release" event. And fixed-version interfaces are a bit of a hack.

Viewporter is one of the most useful protocol extensions, allowing to set the source rectangle on an attached buffer and the destination dimensions. This significantly simplifies scaling, both in implementation and in communicating intent to the server, and makes things like texture atlases possible. It is such an essential and useful extension, that it should have been in the core protocol as the default way to attach buffers to surfaces.

While wl_seat is a wonderful idea (multi-seat actually is a real use case, unlike X forwarding, which is just a workaround for poor software), wl_output should not have been part of the core protocol. Clients keeping track of outputs and what output their surfaces are on to determine scale, amongst other rendering details, is bad design. Modern Wayland agrees and tries to rectify this by informing the client the preferred scale and other data on a per-surface level. Ideally clients would not be aware of outputs at all.

Speaking of scale, integer scaling was a mistake. Luckily there is a fractional scale protocol extension that works decently well, but I am not entirely convinced of its design. Something DPI-aware would likely be better. Some clients hack their way to DPI-aware scaling via wl_output with mixed results. The other issue with scaling is that a surface can be on multiple outputs at once. Wayland should have had a way for the client to attach multiple buffers to a surface, one for each scale. Instead, Wayland servers and clients use heuristics to determine which scale is the correct one.

Finally, the most annoying design mistake is keyboard layout handling. At the time of writing all Wayland servers use xkbcommon for keyboard handling. This result in keyboard handling being needlessly split across both client and server. Wayland clients are send raw key codes from the server and also a giant multi-step look-up-table to find out which key symbol the key code relates to. Of course the server itself already knows this; it has the same look-up-table. A better design would be for the server to just send the final key symbol. Luckily this can potentially be fixed retroactively: The keymap format is not completely hard-coded but identified by an enum. A better format, or the absence of a keymap, could be added to the enum later. Of course clients would still need to support the xkbcommon keymaps for at least a few years after that still.